﻿using System;
using System.Xml;
using System.Xml.XPath;
using System.Globalization;
using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.WebTesting;
using Microsoft.VisualStudio.TestTools.WebTesting.Rules;

namespace WebServicesTesting.Automation.WebTest.ExtractionRules
{
    public class XPathExtraction : ExtractionRule
    {
        private string xPathExpression;

        /// <summary>
        /// This is our XPath Expression
        /// </summary>
        [Description("XPath Expression to evaluate against the response")]
        public string XPathExpression
        {
            get { return xPathExpression; }
            set { xPathExpression = value; }
        }

        /// <summary>
        /// This is our Extraction method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public override void Extract(object sender, ExtractionEventArgs e)
        {
          
            XmlDocument doc = e.Response.XmlDocument;

            // Create a new namespace manager with the response's name table
            XmlNamespaceManager nsMgr =
                new XmlNamespaceManager(doc.NameTable);
            nsMgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");

            // Create a XPath navigator over the document, and select the body
            // node
            XPathNavigator nav = doc.CreateNavigator();
            XmlNode responseBody = doc.SelectSingleNode("//soap:Body", nsMgr);

            // Get the response namespace, and add it to our namespace
            // manager with the prefix "response"
            string responseNS =
                responseBody.FirstChild.Attributes["xmlns"].Value;
            if (responseNS != null && responseNS.Length > 0)
            {
                nsMgr.AddNamespace("response", responseNS);
            }

            // Now, we can evaluate our XPath expression
            XPathNodeIterator iterator =
                nav.Evaluate(xPathExpression, nsMgr) as XPathNodeIterator;
            if (iterator.Count > 0)
            {
                //
                //  Collect the complete value of the iterator
                //
                string value = string.Empty;
                while (iterator.MoveNext())
                {
                    value += iterator.Current.Value;
                }

                //  Indicate success, and set the Context Parameter
                //  selected by the user to the value of the XPath
                //  expression
                e.Success = true;
                e.WebTest.Context.Add(this.ContextParameterName, value);
            }
            else
            {
                // Indicate failure, and populate a message with some
                // explanation of the failure
                e.Success = false;
                e.Message = string.Format(
                    CultureInfo.CurrentCulture,
                    "No result for query: {0}",
                    xPathExpression);
            }
           

        } // method Extract

        // method Extract

        /// <summary>
        /// This method returns the Name of our Rule.
        /// </summary>
        public override string RuleName
        {
            get { return "XPath Extraction Rule"; }
        }


    }
}